<?php
/**
	+----------------------------------------------------------
	* NR 上传类 
	* Author: NightRains  E-mail: upme7@163.com
	* @NR 扩展库文件 update: 2010-2-18
	+----------------------------------------------------------
*/
class Upload extends base{
	//上传文件信息
	var $files = array();
	//允许的文件类型,在配置文件里设置
	var $allowType  = null;
	//允许文件大小
	var $maxSize  = null;
	//文件保存跟路径
	var $savePath = null;
	//错误信息
	var $errInfo  = false;
	/**
		+----------------------------------------------------------
		* 构造函数,完成文件信息格式化,文件检查,上传操作
		* 多文件上传设计,单个文件上传时,表单字段名后加 []
		* <input name="userfile[]" type="file" />
		+----------------------------------------------------------
	*/
	function Upload($allowType=null,$maxsize='0'){
		//设置上传根目录
		$this->savePath = ROOT_PATH."upload/";
		//获取文件大小限制
		if($maxsize > 0){
			$this->maxSize = $maxsize * 1024 * 1024;
		}else{
			$this->maxSize = intval(C("max_file_size"))*1024*1024;//默认设置为4m
			if(!is_numeric($this->maxSize)){//单位B
				$this->maxSize = 4*1024*1024;
			}
		}
		$this->maxSize = get_max_file_size($this->maxSize/1024);
		$this->allowType = $allowType;
		//获取可上传文件类型
		if($this->allowType==null){
			$this->allowType = strtolower(C("allow_ext"));
		}
		//数据格式化
		$this->covnFiles($_FILES);
		//过滤无效,初始化上传数据
		$tmpArr = $this->files;
		$this->files = array();
		for($k=0;$k<sizeof($tmpArr);$k++){
			if($tmpArr[$k]["name"]!=""){
				if($tmpArr[$k]['error']==1 ||$tmpArr[$k]['error']==2){
					$this->errInfo[] = '文件大小超过限制! 请勿超过'.($this->maxSize/1024).' KB!';
					break;
				}
				$tmpArr[$k]['ext']       = $this->getExt($tmpArr[$k]["tmp_name"],$tmpArr[$k]["name"]);
				$tmpArr[$k]['savePath']  = $this->getSavePath($tmpArr[$k]["ext"]);
				$tmpArr[$k]['saveName']  = $this->getSaveName($tmpArr[$k]['ext']);
				$tmpArr[$k]['urlPath']   = $tmpArr[$k]["ext"]."/".$tmpArr[$k]['saveName'];
				$this->files[] = $tmpArr[$k];
			}
		}
		if(!$this->errInfo){
			if(sizeof($this->files)==0){
				//无文件
				$this->errInfo[] = "请选择待上传文件!";
			}else{
				for($i=0;$i<sizeof($this->files);$i++){
					//检查上传
					$rs = $this->chk($this->files[$i]);
					if($rs==""){
						if(!$this->save($this->files[$i])){
							$this->errInfo[] = "未知上传错误!";
						}
					}else{
						$this->errInfo[] = $rs;
					}
				}
			}

		}
	}
	/**
		+----------------------------------------------------------
		* 保存[ 把缓存文件挪至NR系统目录下 ]
		+----------------------------------------------------------
	*/
	function save($file){
		return move_uploaded_file($file["tmp_name"],$file["savePath"].$file["saveName"]);
	}
	/**
		+----------------------------------------------------------
		* 转换上传文件数组变量为正确的方式
		+----------------------------------------------------------
	*/
	function chk($file){
		//提交检查
		if(!$this->checkUpload($file["tmp_name"])){
			return  "非法提交!";
		}
		//大小检查
		if($file["size"]>($this->maxSize)){
			return $file["name"]." ( ".intval($file["size"]/1024)." KB ) 大小超过限制,请勿超过 ".intval(($this->maxSize)/1024)." KB";
		}
		//类型检查
		if(strrpos($this->allowType,strtolower($file["ext"]))===false){
			return $file["ext"]." 类型不允许" ;
		}
		return "";
	}

	/**
		+----------------------------------------------------------
		* 格式化数组数据结构
		+----------------------------------------------------------
	*/
	function covnFiles($files) {
		$fileArray = array();
		if(is_array($files)){
			foreach ($files as  $file){
				if(is_array($file['name'])) {
					$keys = array_keys($file);
					$count    =   count($file['name']);
					for ($i=0; $i<$count; $i++) {
						foreach ($keys as $key) {
							$fileArray[$i][$key] = $file[$key][$i];
						}
					}
				}else{
					$fileArray = $files;
				}
				break;
			}
		}
		$this->files = $fileArray;
	}

	/**
		+----------------------------------------------------------
		* 获取文件保存目录,默认: $this->savePath/文件扩展名/
		+----------------------------------------------------------
	*/
	function getSavePath($fileExt){
		if(!is_dir($this->savePath.$fileExt."/")){
			if(!@mkdir($this->savePath.$fileExt."/")){
				throwException("无法创建上传目录! 请检查权限设置!",__file__,__line__);
				return false;
			}
		}
		return $this->savePath.$fileExt."/";
	}
	/**
		+----------------------------------------------------------
		* 获取文件名(时间+随机4位字符作为文件标识)
		+----------------------------------------------------------
	*/
	function getSaveName($fext){
		return C("file_suffix").date("YmdHis").strtolower(rand_string(12,1)).$this->fName.".".$fext;

	}
	/**
		+----------------------------------------------------------
		* 获取文件扩展名
		+----------------------------------------------------------
	*/
	function getExt($filename,$rpath){
		$s = pathinfo($rpath);
		if($s['extension']=='txt'){
			return $s['extension'];
		}
		if($s['extension']=='html'|$s['extension']=='htm'){
			return $s['extension'];
		}
		if(!file_exists($filename)){
			return "unkown";
		}
		$file = fopen($filename, "rb");
		$bin  = fread($file, 2);
		@fclose($file);
		$strInfo  = @unpack("C2chars", $bin);
		$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
		$fileType = '';
		switch ($typeCode){
			case 7790:
				$fileType = 'exe';
				break;
			case 7784:
				$fileType = 'midi';
				break;
			case 8075:
				$fileType = 'zip';
				break;
			case 8297:
				$fileType = 'rar';
				break;
			case 255216:
				$fileType = 'jpg';
				break;
			case 7173:
				$fileType = 'gif';
				break;
			case 6677:
				$fileType = 'bmp';
				break;
			case 13780:
				$fileType = 'png';
				break;
			case 208194:
				$fileType = 'txt';
				break;
			default:
				$fileType = 'unknown';
		}
		return $fileType;

	}
	/**
		+----------------------------------------------------------
		* 检测提交
		+----------------------------------------------------------
	*/
	function checkUpload($filename){
		return is_uploaded_file($filename);
	}
}
?>